﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace TagPropagator
{
    public class GraphBuilder
    {
        public IComparer Comparer { get; set; }
        public IFeatureExtracor FeatureExtractor { get; set; }
        public IPropagationAgent PropagationAgent { get; set; }
        public IPurgeAgent PurgeAgent { get; set; }
        public ISerializer Serializer { get; set; }
        public Graph Graph { get; set; }

        public GraphBuilder(IComparer comparer, ISerializer serializer)
        {
            Comparer = comparer;
            Serializer = serializer;
        }

        public GraphBuilder(Graph graph, IComparer comparer, IFeatureExtracor featureExtractor, IPropagationAgent propagationAgent, IPurgeAgent purgeAgent, ISerializer serializer)
        {
            Graph = graph;
            Comparer = comparer;
            FeatureExtractor = featureExtractor;
            PropagationAgent = propagationAgent;
            PurgeAgent = purgeAgent;
            Serializer = serializer;
        }

        public void AddNodes(Graph graph)
        {
            foreach (var node in graph.Nodes)
            {
                using (Image i = node.ImageFile)
                {
                    node.Features = FeatureExtractor.ExtractFeatures(i);
                }
                node.ID = Graph.Nodes.Count;
                foreach (var n in Graph.Nodes)
                {
                    double similarity = Comparer.Compare(node, n);
                    n.Neighbours.Add(node.ID, similarity);
                    node.Neighbours.Add(n.ID, similarity);
                }
                Graph.Nodes.Add(node);
                Console.WriteLine(node.ID + "/" + graph.Nodes.Count);
            }
        }

        public void AddNode(Node node) 
        {
            using (Image i = node.ImageFile)
            {
                node.Features = FeatureExtractor.ExtractFeatures(i);
            }
            node.ID = Graph.Nodes.Count;
            foreach (var n in Graph.Nodes)
            {
                double similarity = Comparer.Compare(node, n);
                n.Neighbours.Add(node.ID, similarity);
                node.Neighbours.Add(n.ID, similarity);
            }
            Graph.Nodes.Add(node);
        }

        public void Purge(double similarityLimit)
        {
            PurgeAgent.Purge(Graph, similarityLimit);
        }

        public void PropagateKnowledge(int iterations)
        {
            PropagationAgent.Propagate(Graph, iterations);
        }

        public void Save(String filePath)
        {
            Serializer.Serialize(Graph, filePath);
        }

        public void Load(String filePath)
        {
            System.GC.Collect();
            Graph = Serializer.Deserialize(filePath);
            Console.WriteLine("Building towers");
            System.GC.Collect();
            //foreach (var node in Graph.Nodes)
            //{
            //    using (Image i = node.ImageFile)
            //    {
            //        node.Features = FeatureExtractor.ExtractFeatures(i);
            //    }
            //}
        }
    }
}
